<template>
  <div class="smart-image-wrapper" :style="wrapperStyle">
    <el-image
      v-bind="attrs"
      :src="optimizedSrc"
      :fit="fit"
      :lazy="lazy"
      :preview-src-list="preview ? [realSrc] : []"
      @load="handleLoad"
      @error="handleError"
    >
      <template #placeholder>
        <div
          class="flex items-center justify-center h-full text-gray-400 text-sm"
        >
          加载中...
        </div>
      </template>
      <template #error>
        <div
          class="flex items-center justify-center h-full text-red-400 text-sm"
        >
          加载失败
        </div>
      </template>
    </el-image>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, useAttrs } from "vue";

interface Props {
  /** 图片路径（本地或远程） */
  src: string;
  /** 是否懒加载 */
  lazy?: boolean;
  /** 是否可预览 */
  preview?: boolean;
  /** 填充方式 */
  fit?: "fill" | "contain" | "cover" | "none" | "scale-down";
  /** 宽度 */
  width?: string | number;
  /** 高度 */
  height?: string | number;
  /** 大图是否启用压缩预览 */
  compress?: boolean;
  /** 压缩质量（0~1） */
  quality?: number;
}

const props = withDefaults(defineProps<Props>(), {
  lazy: true,
  preview: false,
  fit: "cover",
  width: "auto",
  height: "auto",
  compress: true,
  quality: 0.7
});

const attrs = useAttrs();

const loaded = ref(false);
const realSrc = ref(props.src);
const optimizedSrc = ref(props.src);

const wrapperStyle = computed(() => ({
  width: typeof props.width === "number" ? `${props.width}px` : props.width,
  height: typeof props.height === "number" ? `${props.height}px` : props.height,
  overflow: "hidden",
  display: "inline-block"
}));

/**
 * 本地大图片压缩优化逻辑：
 * - 如果是本地文件（非 http 开头）
 * - 使用 createImageBitmap + canvas 压缩
 */
async function optimizeLocalImage(src: string) {
  if (!props.compress) return src;
  if (/^https?:\/\//.test(src)) return src;

  try {
    const img = await fetch(src).then(r => r.blob());
    const bitmap = await createImageBitmap(img);
    const canvas = document.createElement("canvas");
    const scale = Math.min(1, 800 / bitmap.width); // 最大宽度800px
    canvas.width = bitmap.width * scale;
    canvas.height = bitmap.height * scale;

    const ctx = canvas.getContext("2d")!;
    ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);

    return canvas.toDataURL("image/jpeg", props.quality);
  } catch (err) {
    console.warn("本地图片压缩失败:", err);
    return src;
  }
}

async function handleLoad() {
  loaded.value = true;
}

function handleError() {
  optimizedSrc.value = "/default-image.png"; // 替换为你的默认图
}

optimizeLocalImage(props.src).then(res => {
  optimizedSrc.value = res;
});
</script>

<style scoped>
.smart-image-wrapper {
  position: relative;
  border-radius: 0.5rem;
  background-color: #f6f6f6;
}
</style>
